﻿using CPPEI.Coolzon.UI.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.UI
{
    public abstract class EventProxy
    {
        public Views.RenderView RenderView { get; private set; }
        public ServiceProxy.MainServiceRef.MainServiceClient MainServiceClient { get; private set; }

        public void SetRenderView(Views.RenderView renderView)
        {
            RenderView = renderView;
        }

        public void SetMainServiceClient(ServiceProxy.MainServiceRef.MainServiceClient mainServiceClient)
        {
            MainServiceClient = mainServiceClient;
        }

        protected List<ISwitchEventReceiver> _switchEventReceiverList;
        protected IPartEventReceiver _partEventReceiver;
        protected List<IScrollEventReceiver> _scrollEventReceiverList;

        public EventProxy()
        {
            _switchEventReceiverList = new List<ISwitchEventReceiver>();
            _scrollEventReceiverList = new List<IScrollEventReceiver>();
        }

        /// <summary>
        /// 注册接收器
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="receiver"></param>
        public void RegisterReceiver<T>(T receiver)
        {
            if (typeof(T) == typeof(ISwitchEventReceiver))
            {
                _switchEventReceiverList.Add((ISwitchEventReceiver)receiver);
            }
            else if (typeof(T) == typeof(IPartEventReceiver))
            {
                if (_partEventReceiver != null)
                {
                    throw new Exception("IPartEventReceiver事件接受者只能绑定一次");
                }
                _partEventReceiver = (IPartEventReceiver)receiver;
            }
            else if (typeof(T) == typeof(IScrollEventReceiver))
            {
                _scrollEventReceiverList.Add((IScrollEventReceiver)receiver);
            }
        }
    }

    /// <summary>
    /// 远程的事件代理
    /// </summary>
    public class RemoteEventProxy : EventProxy, ServiceProxy.MainServiceRef.IMainServiceCallback, ISwitchEventReceiver, IPartEventReceiver, IScrollEventReceiver
    {
        private static RemoteEventProxy s_instance;

        public static RemoteEventProxy Instance
        {
            get
            {
                if (s_instance == null)
                {
                    s_instance = new RemoteEventProxy();
                }
                return s_instance;
            }
        }


        private RemoteEventProxy()
        {
        }

        #region event from event bus
        public void OnSwitch(SwitchMode mode, string frameName, string type, string name, object data)
        {
            // 将事件转交给服务器
            if (mode == SwitchMode.Replace)
            {
                MainServiceClient.ReplaceScene(UIContext.Current.ControlDomainId,
                    UIContext.Current.UserIdentity,
                    frameName,
                    name,
                    string.Empty);
            }
            else if (mode == SwitchMode.Pop)
            {
                MainServiceClient.PopupScene(UIContext.Current.ControlDomainId,
                    UIContext.Current.UserIdentity,
                    frameName,
                    name,
                    string.Empty);
            }
        }

        public void OnPartEvent(EventContext context)
        {
            //throw new NotImplementedException();
        }

        public void OnScrollToArea(string frameName, Metadata.Solution solution, Metadata.Scene scene, Metadata.Area area)
        {
            //throw new NotImplementedException();
            this.RenderView.ScrollToArea(scene, area);
        }
        #endregion

        #region event from mainservice

        public void UserEnterControlDomain(string controlDomain, ServiceProxy.MainServiceRef.UserInfo user)
        {
            throw new NotImplementedException();
        }

        public IAsyncResult BeginUserEnterControlDomain(string controlDomain, ServiceProxy.MainServiceRef.UserInfo user, AsyncCallback callback, object asyncState)
        {
            throw new NotImplementedException();
        }

        public void EndUserEnterControlDomain(IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 收到来自服务器的替换场景事件
        /// </summary>
        /// <param name="userIdentity"></param>
        /// <param name="frameName"></param>
        /// <param name="sceneName"></param>
        /// <param name="parameterString"></param>
        public void OnReplaceScene(string userIdentity, string frameName, string sceneName, string parameterString)
        {
            for (int index = 0; index < this._switchEventReceiverList.Count; index++)
            {
                this._switchEventReceiverList[index].OnSwitch(SwitchMode.Replace, frameName, "Scene", sceneName, null);
            }
        }

        public IAsyncResult BeginOnReplaceScene(string userIdentity, string frameName, string sceneName, string parameterString, AsyncCallback callback, object asyncState)
        {
            throw new NotImplementedException();
        }

        public void EndOnReplaceScene(IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        public void OnPopupScene(string userIdentity, string frameName, string sceneName, string parameterString)
        {
            throw new NotImplementedException();
        }

        public IAsyncResult BeginOnPopupScene(string userIdentity, string frameName, string sceneName, string parameterString, AsyncCallback callback, object asyncState)
        {
            throw new NotImplementedException();
        }

        public void EndOnPopupScene(IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    /// <summary>
    /// 本地事件代理类
    /// </summary>
    public class LocalEventProxy : EventProxy, ServiceProxy.MainServiceRef.IMainServiceCallback, ISwitchEventReceiver, IPartEventReceiver, IScrollEventReceiver, IShowQueryPanelEventReceiver
    {
        private static LocalEventProxy s_instance;

        public static LocalEventProxy Instance
        {
            get
            {
                if (s_instance == null)
                {
                    s_instance = new LocalEventProxy();
                }
                return s_instance;
            }
        }

        private LocalEventProxy()
        {
        }

        #region event from event bus
        public void OnSwitch(SwitchMode mode, string frameName, string type, string name, object data)
        {
            // 将事件转交给服务器
            RenderView.OnSwitch(mode, frameName, type, name, data);
        }

        public void OnPartEvent(EventContext context)
        {
            //throw new NotImplementedException();
        }

        public void OnScrollToArea(string frameName, Metadata.Solution solution, Metadata.Scene scene, Metadata.Area area)
        {
            //throw new NotImplementedException();
        }
        #endregion

        #region event from mainservice

        public void UserEnterControlDomain(string controlDomain, ServiceProxy.MainServiceRef.UserInfo user)
        {
            throw new NotImplementedException();
        }

        public IAsyncResult BeginUserEnterControlDomain(string controlDomain, ServiceProxy.MainServiceRef.UserInfo user, AsyncCallback callback, object asyncState)
        {
            throw new NotImplementedException();
        }

        public void EndUserEnterControlDomain(IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 收到来自服务器的替换场景事件
        /// </summary>
        /// <param name="userIdentity"></param>
        /// <param name="frameName"></param>
        /// <param name="sceneName"></param>
        /// <param name="parameterString"></param>
        public void OnReplaceScene(string userIdentity, string frameName, string sceneName, string parameterString)
        {
            // 转交给renderview
            RenderView.SwitchToScene(sceneName);
        }

        public IAsyncResult BeginOnReplaceScene(string userIdentity, string frameName, string sceneName, string parameterString, AsyncCallback callback, object asyncState)
        {
            throw new NotImplementedException();
        }

        public void EndOnReplaceScene(IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        public void OnPopupScene(string userIdentity, string frameName, string sceneName, string parameterString)
        {
            throw new NotImplementedException();
        }

        public IAsyncResult BeginOnPopupScene(string userIdentity, string frameName, string sceneName, string parameterString, AsyncCallback callback, object asyncState)
        {
            throw new NotImplementedException();
        }

        public void EndOnPopupScene(IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        #endregion

        public void OnShowQueryPanel(object partInstance, object partMetadata)
        {
            if (partInstance is ControlPart)
            {
                // 控件组件
                UIContext.Current.RootViewContainer.PopView(new QueryView(((Metadata.Part)partMetadata).Parameters));
            }
            else
            {
                // 场景组件
                UIContext.Current.RootViewContainer.PopView(new QueryView(((Metadata.Scene)partMetadata).Parameters));
            }
        }
    }

}
